package cn.iocoder.yudao.module.erp.service.customeraccount;

import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.erp.dal.dataobject.accountplanrecord.AccountPlanRecordDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.customerinfo.CustomerInfoDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.payinfo.PayInfoDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.planinfo.PlanInfoDO;
import cn.iocoder.yudao.module.erp.dal.mysql.accountplanrecord.AccountPlanRecordMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.customerinfo.CustomerInfoMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.payinfo.PayInfoMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.planinfo.PlanInfoMapper;
import cn.iocoder.yudao.module.erp.enums.Constant;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import cn.iocoder.yudao.module.erp.controller.admin.customeraccount.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.customeraccount.CustomerAccountDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.erp.dal.mysql.customeraccount.CustomerAccountMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;

/**
 * 客户余额 Service 实现类
 *
 * @author mhc
 */
@Service
@Validated
public class CustomerAccountServiceImpl implements CustomerAccountService {

    @Resource
    private CustomerAccountMapper customerAccountMapper;

    @Resource
    private CustomerInfoMapper customerInfoMapper;

    @Resource
    private PlanInfoMapper planInfoMapper;

    @Resource
    private AccountPlanRecordMapper accountPlanRecordMapper;

    @Resource
    private PayInfoMapper payInfoMapper;

    @Override
    public boolean calculateCustomerAccountCount() {
        //重新计算当前用户余额
        List<CustomerInfoDO> customerInfoDOList=customerInfoMapper.selectList();
        for(CustomerInfoDO customer:customerInfoDOList){
            //计算计划金额
            List<PlanInfoDO> planList=planInfoMapper.selectList(new LambdaQueryWrapperX<PlanInfoDO>().eq(PlanInfoDO::getBuyCustomerId,customer.getId()).or()
                    .eq(PlanInfoDO::getSaleCustomerId,customer.getId()));
            BigDecimal nowCount=new BigDecimal("0");
            BigDecimal buyCount=new BigDecimal("0");
            BigDecimal saleCount=new BigDecimal("0");

            if(planList!=null&&!planList.isEmpty()){
                for(PlanInfoDO plan:planList){
                    if(plan.getSaleCustomerId().intValue()==customer.getId().intValue()){
                        //得到计算
                        AccountPlanRecordDO ap=accountPlanRecordMapper.selectOne(new LambdaQueryWrapper<AccountPlanRecordDO>().eq(AccountPlanRecordDO::getCustomerId,plan.getSaleCustomerId())
                                .eq(AccountPlanRecordDO::getTypeId,plan.getId()).eq(AccountPlanRecordDO::getType, Constant.AccountPlanRecord_TYPE.销售.getValue()));
                        if(ap!=null){
                            BigDecimal saleAllCount=plan.getSaleAllCount().abs().negate();
                            ap.setMoneyCount(saleAllCount);
                            accountPlanRecordMapper.updateById(ap);
                        }else{
                            ap=new AccountPlanRecordDO();
                            ap.setCustomerId(plan.getSaleCustomerId());
                            ap.setMoneyCount(plan.getSaleAllCount().abs().negate());
                            ap.setType(Constant.AccountPlanRecord_TYPE.销售.getValue());
                            ap.setTypeId(plan.getId());
                            ap.setPayDate(plan.getNowTime());
                            accountPlanRecordMapper.insert(ap);
                        }
                        nowCount=nowCount.add(plan.getSaleAllCount().abs().negate());
                        saleCount=saleCount.add(plan.getSaleAllCount().abs());
                    }
                    if(plan.getBuyCustomerId().intValue()==customer.getId().intValue()){
                        AccountPlanRecordDO cg=accountPlanRecordMapper.selectOne(new LambdaQueryWrapper<AccountPlanRecordDO>().eq(AccountPlanRecordDO::getCustomerId,plan.getBuyCustomerId())
                                .eq(AccountPlanRecordDO::getTypeId,plan.getId()).eq(AccountPlanRecordDO::getType,Constant.AccountPlanRecord_TYPE.采购.getValue()));
                        if(cg!=null){
                            cg.setMoneyCount(plan.getBuyAllCount().abs());
                            accountPlanRecordMapper.updateById(cg);
                        }else{
                             cg=new AccountPlanRecordDO();
                            cg.setCustomerId(plan.getBuyCustomerId());
                            cg.setMoneyCount(plan.getBuyAllCount().abs());
                            cg.setType(Constant.AccountPlanRecord_TYPE.采购.getValue());
                            cg.setTypeId(plan.getId());
                            cg.setPayDate(plan.getNowTime());

                            accountPlanRecordMapper.insert(cg);
                        }

                        nowCount=nowCount.add(plan.getBuyAllCount().abs());
                        buyCount=buyCount.add(plan.getBuyAllCount().abs());

                    }
                }
            }

            //计算打款金额
            List<PayInfoDO> payList=payInfoMapper.selectList(new LambdaQueryWrapperX<PayInfoDO>().eq(PayInfoDO::getCustomerId,customer.getId()));
            if(payList!=null&&!payList.isEmpty()){
                for(PayInfoDO payInfo:payList){
                    //我方收款
                    if(payInfo.getType().equals("3")){
                        payInfo.setPayCount(payInfo.getPayCount().abs());
                        nowCount=nowCount.add(payInfo.getPayCount().abs());
                        //我方付款
                    }else if(payInfo.getType().equals("4")){
                        payInfo.setPayCount(payInfo.getPayCount().abs().negate());
                        nowCount=nowCount.add(payInfo.getPayCount().abs().negate());
                    }
                    payInfoMapper.updateById(payInfo);
                }
            }

            customer.setNowCount(nowCount);
            customer.setBuyCount(buyCount);
            customer.setSaleCount(saleCount);
            customerInfoMapper.updateById(customer);

        }

        return false;
    }

    @Override
    public Long createCustomerAccount(CustomerAccountSaveReqVO createReqVO) {
        // 插入
        CustomerAccountDO customerAccount = BeanUtils.toBean(createReqVO, CustomerAccountDO.class);
        customerAccountMapper.insert(customerAccount);
        // 返回
        return customerAccount.getId();
    }

    @Override
    public void updateCustomerAccount(CustomerAccountSaveReqVO updateReqVO) {
        // 校验存在
        validateCustomerAccountExists(updateReqVO.getId());
        // 更新
        CustomerAccountDO updateObj = BeanUtils.toBean(updateReqVO, CustomerAccountDO.class);
        customerAccountMapper.updateById(updateObj);
    }

    @Override
    public void deleteCustomerAccount(Long id) {
        // 校验存在
        validateCustomerAccountExists(id);
        // 删除
        customerAccountMapper.deleteById(id);
    }

    private void validateCustomerAccountExists(Long id) {
        if (customerAccountMapper.selectById(id) == null) {
            throw exception(CUSTOMER_ACCOUNT_NOT_EXISTS);
        }
    }

    @Override
    public CustomerAccountDO getCustomerAccount(Long id) {
        return customerAccountMapper.selectById(id);
    }

    @Override
    public PageResult<CustomerAccountDO> getCustomerAccountPage(CustomerAccountPageReqVO pageReqVO) {
        return customerAccountMapper.selectPage(pageReqVO);
    }

}